package cn.anecansaitin.not_enough_harness.common.harness_data;

import cn.anecansaitin.not_enough_harness.common.ModDataMap;
import cn.anecansaitin.not_enough_harness.common.item.ModComponents;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;

public record RushTriggerHarness(int cd, int duration, float speed, Vec3 direction) {
    public static final RushTriggerHarness ZERO = new RushTriggerHarness(0, 0, 0, Vec3.ZERO);

    public static final Codec<RushTriggerHarness> CODEC = RecordCodecBuilder.create(
            instance ->
                    instance.group(
                                    Codec.INT.fieldOf("cd").forGetter(RushTriggerHarness::cd),
                                    Codec.INT.fieldOf("duration").forGetter(RushTriggerHarness::duration),
                                    Codec.FLOAT.fieldOf("speed").forGetter(RushTriggerHarness::speed),
                                    Vec3.CODEC.fieldOf("direction").forGetter(RushTriggerHarness::direction)
                            )
                            .apply(instance, RushTriggerHarness::new)
    );

    public static final Codec<RushTriggerHarness> SYNC_CODEC = RecordCodecBuilder.create(
            instance ->
                    instance.group(
                                    Codec.INT.fieldOf("0").forGetter(RushTriggerHarness::cd),
                                    Codec.INT.fieldOf("1").forGetter(RushTriggerHarness::duration),
                                    Codec.FLOAT.fieldOf("2").forGetter(RushTriggerHarness::speed),
                                    Vec3.CODEC.fieldOf("3").forGetter(RushTriggerHarness::direction)
                            )
                            .apply(instance, RushTriggerHarness::new)
    );

    public static final StreamCodec<FriendlyByteBuf, RushTriggerHarness> STREAM_CODEC = StreamCodec.composite(
            ByteBufCodecs.VAR_INT, RushTriggerHarness::cd,
            ByteBufCodecs.VAR_INT, RushTriggerHarness::duration,
            ByteBufCodecs.FLOAT, RushTriggerHarness::speed,
            Vec3.STREAM_CODEC, RushTriggerHarness::direction,
            RushTriggerHarness::new
    );

    @NotNull
    public static RushTriggerHarness get(ItemStack item) {
        RushTriggerHarness rushTriggerHarness = item.get(ModComponents.RUSH_TRIGGER_HARNESS);

        if (rushTriggerHarness == null) {
            RushTriggerHarness dataMap = item.getItemHolder().getData(ModDataMap.RUSH_TRIGGER_HARNESS);

            if (dataMap == null) {
                dataMap = RushTriggerHarness.ZERO;
            }

            item.set(ModComponents.RUSH_TRIGGER_HARNESS, dataMap);
            return dataMap;
        }

        return rushTriggerHarness;
    }
}
